import axios from 'axios'
import { mkdirRecursions } from './mkdirRecursions.js'
import config from './pont.config.js'
import { cwd } from 'node:process';
import fs from 'fs'
//获取swagger.json //支持多目录
async function getInit() {
    let content = ''
    for (let i in config.url) {
        //生成api文件 根据/分割的第二个为文件名称
        let res = await axios.get(config.url[i])
        let data = res.data
        let paths = data.paths

        await mkdirRecursions(cwd() + config.baseUrl + config.path)
        //给d.ts文件赋值
        content += getWritedTs(data.definitions)
        //如果是最后一个再生成d.ts文件
        if (parseInt(i) === config.url.length - 1) {
            //生成RestResult默认回调
            content += `
type RestResult<T = any> = T //回调泛型`
            //生成默认list泛型
            content += `
type List<T = any> = T[] //List泛型`

            fs.writeFile(cwd() + config.baseUrl + config.path + 'types.d.ts', content, () => { })
        }
        let fileNames = {}
        for (let i in paths) {
            if (fileNames[i.split("/")[2]] === undefined) {
                fileNames[i.split("/")[2]] = []
            }
            fileNames[i.split("/")[2]].push({ path: i, ...paths[i] })
        }
        for (let i in fileNames) {
            await mkdirRecursions(cwd() + config.baseUrl + config.path + i)//新建文件夹
        }
        for (let i in fileNames) {
            //新建文件
            fs.writeFile(cwd() + config.baseUrl + config.path + i + '/index.ts', getWriteFile(fileNames[i]), () => {
            })
        }
        console.log('生成成功')
    }

}

//类型转化 java类型转ts类型
function JAVAChangeTsType(current, isGenerics) {
    if (current.type === 'integer') {
        return 'number | string'
    }
    if (current.type === 'array') {
        //如果是泛型就生成泛型的数组
        if (isGenerics) {
            return `T[]`
        }
        if (current.items.originalRef) {
            return `${current.items.originalRef}[]`
        } else {
            return `${JAVAChangeTsType(current.items)}[]`
        }
    }
    //默认扩展类型
    if (current.originalRef) {
        return current.originalRef
    }
    return current.type
}
//生成接口d.ts文件
function getWritedTs(definitions) {
    //RestResult下的不生成
    let content = ''
    let genericsObj = {}
    for (let i in definitions) {
        //泛型数组提取
        if (i.search(/«/) !== -1 && i.search(/^RestResult/) === -1) {
            genericsObj[i.split('«')[0]] = definitions[i]
        }
        if (i.search(/^RestResult|-|«/) === -1) {
            let required = definitions[i].required || []

            //生成type Params
            if (i.search(/Param/) !== -1) {
                content += `
type ${i} = {`
            } else {
                //继承定义
                content += `
interface ${i} {`
            }
            for (let j in definitions[i].properties) {
                let type = JAVAChangeTsType(definitions[i].properties[j])
                let description = definitions[i].properties[j].description
                content += `
    ${j}${(required.indexOf(j) === -1 || j === 'appKey' || j === 'timestamp') ? '?' : ''}: ${type} ${description ? '//' + description : ''}`
            }

            content += `
}`
        }
    }
    //生成泛型
    for (let i in genericsObj) {
        content += `
interface ${i}<T>{`
        for (let j in genericsObj[i].properties) {
            let required = genericsObj[i].required || []
            let type = JAVAChangeTsType(genericsObj[i].properties[j], true)
            let description = genericsObj[i].properties[j].description
            content += `
    ${j}${required.indexOf(j) === -1 ? '?' : ''}: ${type} ${description ? '//' + description : ''}`
        }
        content += `
}`
    }

    return content
}
//首字母大写
function fristCapital(str) {
    return str.replace(/^\S/, s => s.toUpperCase())
}
// 生成文件接口内容
function getWriteFile(arr) {
    let content = 'import request from "@/utils/request";'
    for (let i in arr) {
        let reqeuestRef = arr[i].post.responses['200'].schema.originalRef.replace(/«/g, '<').replace(/»/g, '>')
        let interfaceList = arr[i].path.split("/")
        let interfaceName = interfaceList.pop()
        if (interfaceName == 'delete') {
            interfaceName = interfaceList[interfaceList.length - 1] + 'Delete'
        }
        if (arr[i].post.summary.indexOf('导出') !== -1) {
            interfaceName = 'export' + fristCapital(interfaceName)
        }
        let exportBlob = ''
        //如果是导出的就加入导出的参数
        if (arr[i].post.summary.indexOf('导出') !== -1) {
            exportBlob = `, { responseType: 'blob' }`
        }
        content += `
/**
* @exports ${arr[i].post.summary}
* @param params 
* @returns Promise
*/
export const ${interfaceName
            } = (params: ${arr[i].post.parameters[1]?.schema.originalRef || 'any'}) => {
    return request.post<${reqeuestRef}>("${arr[i].path}", params${exportBlob});
}
`
    }
    return content
}

getInit()
